<template>
  <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th v-for="(col) in columns" :key="col.name">
          {{col.name}}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in list" :key="item.id">
        <td v-for="(col, n) in columns" :key="col.name">
          <div class="box-inter" v-if="!n">
            <div class="inter-gap" v-if="item.level">
              <span v-for="m in item.level" :key="m">├</span>
            </div>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
/* 树形表格 */
import strer from '../../../../component/script/strer/2.0.0/js/strer.js'

export default {
  props: {
    // 树形数据
    data: {
      default: {}
    },
    // 子级key
    childKey: {
      default: 'children'
    },
    // 创建节点事件
    onCreateNode: {
      default: function () {}
    }
  },

  data () {
    return {
      // 列表数据
      list: []
    }
  },

  methods: {
    /**
     * @function 获取新节点
     * @param {Object} node 上一节点
     * @param {Boolean} isSub // 是否是子级
     * @return {Object}
    */
    getNewNode (node, isSub) {
      node = node || {level: 0}
      let item = {
        id: strer.utid(),
        pid: isSub ? node.id : (node.pid || 0),
        level: isSub ? node.level + 1 : node.level
      }

      return item
    },

    /**
    * @function 解包层级
    * @param {Array} nodes // 节点数组
    * @param {Object} parent // 父级对象
    * @param {Int} level // 层级
    * @param {Boolean} isNew // 是否新节点
    * @return {Array}
    */
    unPack (nodes, parent, level, isNew) {
      let arr = []
      level = isNaN(level) ? 0 : level
      if (Array.isArray(nodes)) {
        nodes.forEach(item => {
          // 复制参数对象
          let param = {level}
          for (let key in item) {
            if (key !== 'level') {
              param[key] = item[key]
            }
          }
          // 自身id与父id设置
          param.id = isNew === true ? strer.utid() : (item.id || strer.utid())
          param.pid = parent ? parent.id : 0
          // 加入数组
          arr.push(param)
          // 子级
          if (item[this.childKey] && item[this.childKey].length > 0) {
            arr = arr.concat(this.unPack(item[this.childKey], param, level + 1, isNew))
          }
        })
      }

      return arr
    },

    /**
    * @function 组装成树节点
    * @param {Array} nodes // 节点数组
    * @param {Array} parentNodes // 父节点数组
    * @return {Array}
    */
    pack (nodes, parentNodes) {
      // 根参数组
      if (!parentNodes) {
        parentNodes = []
        nodes.forEach(item => {
          if (item.pid === 0) {
            parentNodes.push(item)
          }
        })
      }

      // 遍历父级参数
      parentNodes.forEach(item => {
        nodes.forEach(node => {
          if (node.pid === item.id) {
            if (!item[this.childKey]) {
              item[this.childKey] = []
            }
            item[this.childKey].push(node)
          }
        })
        // 继续查找子参数组
        if (item[this.childKey]) {
          this.pack(nodes, item[this.childKey])
        }
      })

      return parentNodes
    },

    /**
    * @function 查找关联的父级与子级对象
    * @param {Object} item // 参数对象
    * @param {Array<Object>} [items] // 已查找到的数组
    * @return {Array<Object>}
    */
    getRelations (item, items) {
      items = Array.isArray(items) ? items : [item]
      // 遍历参数查找所有子参数
      this.list.forEach(node => {
        if (item.id === node.pid) {
          items.push(node)
          this.getRelations(node, items)
        }
      })

      return items
    },

    /**
     * @function 添加同级节点
    */
    addNode (item) {
      // 参数索引
      let index = this.list.indexOf(item)
      // 关联国际化
      let relaItems = this.getRelations(item)
      let newItem = this.getNewNode(item)
      // 添加新的对象
      this.list.splice(index + relaItems.length, 0, newItem)

      return newItem
    },

    /**
     * @function 添加子级节点
    */
    addSubNode (item) {
      // 参数索引
      let index = this.list.indexOf(item)
      let newItem = this.getNewNode(item, true)
      // 添加新的对象
      this.list.splice(index + 1, 0, newItem)

      return newItem
    },

    /**
     * @function 删除节点
    */
    removeNode (item) {
      // 参数索引
      let index = this.list.indexOf(item)
      let ids = [item.id] // 节点与子节点id集合
      let len = 1 // 删除的节点长度
      // 遍历节点查找所有子节点
      this.list.forEach(node => {
        if (ids.indexOf(node.pid) > -1) {
          ids.push(node.id)
          len += 1
        }
      })

      // 删除参数对象
      this.list.splice(index, len)
    }
  },

  /**
   * @function 挂载前事件处理
  */
  beforeMount () {
    // 解包树数据
    this.list = this.unPack(this.data)
  }
}
</script>

<style>

</style>
